package com.wang.jmonkey.ca.handler.login;

import cn.hutool.core.collection.CollUtil;
import org.springframework.context.ApplicationContext;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * @Description 用户登陆适配器
 * @Author HeJiawang
 * @Date 2021/5/10 17:40
 */
@Component
public class UserServiceHandlerManager implements UserServiceHandlerAdapter {

    private ApplicationContext context;

    private List<UserServiceHandlerAdapter> list = new ArrayList<UserServiceHandlerAdapter>();

    public UserServiceHandlerManager(ApplicationContext context) {
        this.context = context;
    }

    @PostConstruct
    private void init() {
        Map<String, UserServiceHandlerAdapter> map = context.getBeansOfType(UserServiceHandlerAdapter.class);
        if (CollUtil.isEmpty(map)) return;

        map.entrySet().forEach(entry -> {
            if ( !(entry.getValue() instanceof UserServiceHandlerManager) ) {
                list.add(entry.getValue());
            }
        });
    }

    @Override
    public UserDetails handler(String username) {
        if (CollUtil.isEmpty(list)) return null;

        for (UserServiceHandlerAdapter handlerAdapter : list) {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();

            Iterator<String> iterator = request.getAttributeNames().asIterator();
            while(iterator.hasNext()) {
                String name = iterator.next();
                if (request.getAttribute(name) instanceof AbstractAuthenticationProcessingFilter) {

                    AbstractAuthenticationProcessingFilter filter = (AbstractAuthenticationProcessingFilter)request.getAttribute(name);
                    if (handlerAdapter.support(filter)) {
                        return handlerAdapter.handler(username);
                    }
                }
            }
        }

        return null;
    }

    @Override
    public boolean support(AbstractAuthenticationProcessingFilter filter) {
        return false;
    }
}
